using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Dynamic;
using System.Linq;

namespace twistmachinev2
{
    /// <summary>
    /// 动态数据模型，支持根据配置文件动态创建属性
    /// </summary>
    public class DynamicDataModel : DynamicObject, INotifyPropertyChanged
    {
        private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
        private readonly Dictionary<string, OpcUaNodeConfig> _nodeConfigs = new Dictionary<string, OpcUaNodeConfig>();

        public event PropertyChangedEventHandler PropertyChanged;

        // 添加常用的固定属性
        public bool IsConnected { get; set; }
        public string StatusDescription { get; set; } = "未连接";
        public DateTime LastUpdateTime { get; set; } = DateTime.Now;
        public bool AlarmStatus { get; set; }
        public bool MotorStart { get; set; }
        public int MotorSpeed { get; set; }
        public string OperationMode { get; set; } = "手动";
        public int ProductionCount { get; set; }
        public int ErrorCount { get; set; }

        /// <summary>
        /// 启动机器
        /// </summary>
        public void StartMachine()
        {
            MotorStart = true;
            StatusDescription = "运行中";
            OnPropertyChanged(nameof(MotorStart));
            OnPropertyChanged(nameof(StatusDescription));
        }

        /// <summary>
        /// 停止机器
        /// </summary>
        public void StopMachine()
        {
            MotorStart = false;
            MotorSpeed = 0;
            StatusDescription = "已停止";
            OnPropertyChanged(nameof(MotorStart));
            OnPropertyChanged(nameof(MotorSpeed));
            OnPropertyChanged(nameof(StatusDescription));
        }

        /// <summary>
        /// 重置计数器
        /// </summary>
        public void ResetCounters()
        {
            ProductionCount = 0;
            ErrorCount = 0;
            OnPropertyChanged(nameof(ProductionCount));
            OnPropertyChanged(nameof(ErrorCount));
        }

        /// <summary>
        /// 初始化动态数据模型
        /// </summary>
        /// <param name="nodeConfigs">节点配置列表</param>
        public void Initialize(List<OpcUaNodeConfig> nodeConfigs)
        {
            foreach (var config in nodeConfigs)
            {
                if (!string.IsNullOrEmpty(config.PropertyName))
                {
                    // 根据数据类型设置默认值
                    object defaultValue = GetDefaultValue(config.DataType);
                    _properties[config.PropertyName] = defaultValue;
                    _nodeConfigs[config.PropertyName] = config;
                }
            }
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return _properties.TryGetValue(binder.Name, out result);
        }

        /// <summary>
        /// 设置属性值
        /// </summary>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var propertyName = binder.Name;

            // 检查属性是否存在于配置中
            if (!_nodeConfigs.ContainsKey(propertyName))
            {
                return false;
            }

            // 类型转换
            var config = _nodeConfigs[propertyName];
            var convertedValue = ConvertValue(value, config.DataType);

            // 检查值是否发生变化
            if (!_properties.ContainsKey(propertyName) ||
                !Equals(_properties[propertyName], convertedValue))
            {
                _properties[propertyName] = convertedValue;
                OnPropertyChanged(propertyName);
            }

            return true;
        }

        /// <summary>
        /// 通过属性名获取值
        /// </summary>
        public object GetValue(string propertyName)
        {
            return _properties.TryGetValue(propertyName, out var value) ? value : null;
        }

        /// <summary>
        /// 通过属性名设置值
        /// </summary>
        public bool SetValue(string propertyName, object value)
        {
            if (!_nodeConfigs.ContainsKey(propertyName))
            {
                return false;
            }

            var config = _nodeConfigs[propertyName];
            var convertedValue = ConvertValue(value, config.DataType);

            if (!_properties.ContainsKey(propertyName) ||
                !Equals(_properties[propertyName], convertedValue))
            {
                _properties[propertyName] = convertedValue;
                OnPropertyChanged(propertyName);
            }

            return true;
        }

        /// <summary>
        /// 获取所有属性名
        /// </summary>
        public IEnumerable<string> GetPropertyNames()
        {
            return _properties.Keys;
        }

        /// <summary>
        /// 获取节点配置
        /// </summary>
        public OpcUaNodeConfig GetNodeConfig(string propertyName)
        {
            return _nodeConfigs.TryGetValue(propertyName, out var config) ? config : null;
        }

        /// <summary>
        /// 获取所有节点配置
        /// </summary>
        public IEnumerable<OpcUaNodeConfig> GetAllNodeConfigs()
        {
            return _nodeConfigs.Values;
        }

        /// <summary>
        /// 根据数据类型获取默认值
        /// </summary>
        private object GetDefaultValue(string dataType)
        {
            if (string.IsNullOrEmpty(dataType))
                return null;

            switch (dataType.ToLower())
            {
                case "bool":
                case "boolean":
                    return false;
                case "byte":
                    return (byte)0;
                case "short":
                case "int16":
                    return (short)0;
                case "int":
                case "int32":
                    return 0;
                case "long":
                case "int64":
                    return 0L;
                case "float":
                case "single":
                    return 0.0f;
                case "double":
                    return 0.0;
                case "decimal":
                    return 0.0m;
                case "string":
                    return string.Empty;
                case "datetime":
                    return DateTime.MinValue;
                default:
                    return null;
            }
        }

        /// <summary>
        /// 值类型转换
        /// </summary>
        private object ConvertValue(object value, string dataType)
        {
            if (value == null) return GetDefaultValue(dataType);

            try
            {
                if (string.IsNullOrEmpty(dataType))
                    return value;

                switch (dataType.ToLower())
                {
                    case "bool":
                    case "boolean":
                        return Convert.ToBoolean(value);
                    case "byte":
                        return Convert.ToByte(value);
                    case "short":
                    case "int16":
                        return Convert.ToInt16(value);
                    case "int":
                    case "int32":
                        return Convert.ToInt32(value);
                    case "long":
                    case "int64":
                        return Convert.ToInt64(value);
                    case "float":
                    case "single":
                        return Convert.ToSingle(value);
                    case "double":
                        return Convert.ToDouble(value);
                    case "decimal":
                        return Convert.ToDecimal(value);
                    case "string":
                        return value.ToString();
                    case "datetime":
                        if (value is DateTime)
                            return value;
                        else
                            return DateTime.Parse(value.ToString());
                    default:
                        return value;
                }
            }
            catch
            {
                return GetDefaultValue(dataType);
            }
        }

        /// <summary>
        /// 触发属性变化事件
        /// </summary>
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// 获取所有属性的字典表示
        /// </summary>
        public Dictionary<string, object> ToDictionary()
        {
            return new Dictionary<string, object>(_properties);
        }

        /// <summary>
        /// 从字典更新属性
        /// </summary>
        public void FromDictionary(Dictionary<string, object> values)
        {
            foreach (var kvp in values)
            {
                SetValue(kvp.Key, kvp.Value);
            }
        }
    }
}